<template>
  <div ref="ganttwrapper" class="ganttwrapper">
    <div
      id="ganttRef"
      ref="ganttRef"
      class="gantt-no z-h-100"
      style="height: 100%"
    />
    <div class="ganttwrapper__header">
      <dateHeader
        @click="dateClickFun"
        @backToday="backToday"
        @toggleFullscreen="toggleFullscreen"
      />
    </div>
  </div>
</template>

<script>
import GantEvent from "./event.js";
import VueGantt from "./defineGantt.js";
import {
  getEditType,
  hasKey,
  createCheckBoxTemplate,
  getGanttConfigByZoomValue
} from "./utils.js";
import dateHeader from "./dateHeader.vue";
import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
import Dayjs from "dayjs";
import methods from "./methods";
import screenfull from "screenfull";
import Marker from "./marker";
// import gantt from 'dhtmlx-gantt'
const gantt = window.gantt;
export default {
  components: {
    dateHeader
  },
  mixins: [methods],
  props: {
    value: {
      type: Object,
      default: () => {
        return {};
      }
    },
    columns: {
      type: Array,
      default: () => {
        return [];
      }
    },
    gantConfig: {
      type: Object,
      default: () => {
        return {};
      }
    },
    markData: {
      type: Array,
      default: () => {
        return [];
      }
    },
    today: {
      type: Object,
      default: () => {
        return {
          start_date: "2022-15",
          css: "toDay",
          text: "当前时间",
          title: "当前时间",
          style: "background:red"
        };
      }
    },
    isWeekEndShow: {
      // 是否显示周末
      type: Boolean,
      default: false
    },
    durationTime: {
      // 某个时间段添加marks
      type: Array,
      default: () => [1, 5]
    },
    weekendCls: {
      // 周末样式
      type: String,
      default: () => {
        return "weekend";
      }
    },
    isHideMark: {
      type: Boolean,
      default: true
    },
    taskClass: {
      type: Function,
      default: () => undefined
    }
  },
  data() {
    return {
      VueGantt: null,
      gantt,
      defaultLeftWidth: 0,
      marker: null
    };
  },
  computed: {
    isHasToday() {
      return this.today && Object.keys(this.today).length > 0;
    }
  },
  watch: {
    gantConfig: {
      handler(nVal) {
        this.VueGantt.setGantConfig(nVal); // 设置甘特图属性
        this.VueGantt.render();
      },
      deep: true
    },
    // isWeekEndShow (nVal) {
    //   console.log(nVal, 'zzz')
    //   this.setWeekEndIgnore(nVal)
    //   gantt.render()
    // },
    durationTime(nVal) {
      this.setDurationTime(nVal); // 设置某个时间段1-5
      gantt.render();
    },
    isHideMark(nVal) {
      gantt.config.show_markers = nVal;
      gantt.render();
    },
    markData(nVal) {
      this.deleteMarker();
      this.setMarkDataAndToday(nVal); // 设置今天和某个时间段的marks
    }
    // weekendCls (nVal) {
    //   this.setWeekEndCls(nVal) // 设置周末样式
    // }
  },
  mounted() {
    this.$nextTick(() => {
      gantt.config.bar_height = 45;

      this.VueGantt = new VueGantt({ id: "ganttRef", gantt, task: this.value });
      new GantEvent({
        inlineEdit: this.gantConfig.inlineEdit,
        gantt,
        vue: this,
        VueGantt: this.VueGantt
      }).init(); // 主要初始化时间参数
      this.marker = new Marker({ gantt });
      gantt.config.columns = this.columns;
      this.VueGantt.init(this.gantConfig);
      this.defaultLeftWidth = gantt.config.grid_width;
      this.initGantColumnConfig(this.columns);
      this.setMarkDataAndToday(this.markData); // 设置今天和某个时间段的marks
      // this.setToday(this.value.data) // 设置今天marks
      // this.setWeekEndIgnore(this.isWeekEndShow) // 周末不显示
      // this.setDurationTime(this.durationTime) // 设置某个时间段1-5 设置周末样式
      this.setDateUpdate("week");
      this.setGridRowClass();
      this.setTaskClass();
    });
  },
  methods: {
    // 设置业务甘特图配置
    setBussinessGantConfig(data) {
      if (data.weekEnds || data.durationsMarkers) {
        this.setDurationTimeAndWeekEndCls(data.weekEnds, data.durationsMarkers);
      }
      if (data.rowHeight) {
        this.setRowHeight(data.rowHeight);
      }
      gantt.render();
    },
    setRowHeight(string) {
      const map = {
        default: 35,
        small: 30,
        large: 40
      };
      gantt.config.row_height = map[string];
      gantt.config.bar_height = map[string];
    },
    deleteMarker() {
      const targetAll = Object.keys(gantt.getDatastore("marker").pull);
      console.log(Object.keys(gantt.getDatastore("marker").pull), "targetAll");
      this.marker.deleteMarker(targetAll);
    },
    setGridRowClass() {
      this.gantt.templates.grid_row_class = (start, end, task) => {
        const children = this.gantt.getChildren(task.id);
        return children.length > 0 ? "parent_node" : "child_node";
      };
    },
    setTaskClass() {
      this.gantt.templates.task_class = (start, end, task) => {
        const children = this.gantt.getChildren(task.id);
        return children.length > 0 ? "parent_row_class" : "child_row_class";
      };
    },
    toggleFullscreen() {
      const element = this.$refs.ganttwrapper;
      if (!screenfull.enabled) {
        this.$message({
          message: "you browser can not work",
          type: "warning"
        });
        return false;
      }
      screenfull.toggle(element);
    },
    backToday() {
      this.move(new Date());
    },
    dateClickFun(item) {
      const { value } = item;
      this.setDateUpdate(value);
    },
    setDateUpdate(value) {
      gantt.config.scales = getGanttConfigByZoomValue(this.gantt, value);
      gantt.render();
    },
    cacheMarks(key, map, target) {
      if (!map[key]) {
        map[key] = true;
        this.gantt.addMarker(target);
      }
    },
    setDurationTimeAndWeekEndCls(weekEnds, target) {
      console.log(target, "target");
      if (!Array.isArray(target)) {
        target = [target];
      }
      const map = {};
      const start = target[0];
      console.log(start, "start");
      this.deleteMarker();

      gantt.templates.timeline_cell_class = (item, date) => {
        const dateTime = date.getDay();
        const { $y, $M, $D } = Dayjs(date);
        const keys = `${$y}${$M + 1}${$D}`;
        const currentYear = Dayjs(date).format("YYYY-MM-DD");
        if (dateTime === start) {
          this.cacheMarks(keys, map, {
            start_date: new Date($y, $M, $D),
            css: "firstMonday",
            text: currentYear,
            title: "v.title"
          });
          gantt.config.show_markers = true;
        }
        if (weekEnds.includes(dateTime)) {
          return this.weekendCls;
        }
      };
      gantt.render();
      return "";
    },
    setWeekEndIgnore(weekends, status) {
      this.setIgnoreDate(weekends, status); // from methids.js
      gantt.render();
    },
    setMarkData(data) {
      if (Array.isArray(data) && data.length > 0) {
        data.forEach((v) => {
          const startDate = v.start_date;
          const { $y, $M, $D } = Dayjs(startDate);
          const uId = v.id || new Date().getTime();
          gantt.addMarker({
            start_date: new Date($y, $M, $D),
            css: v.css,
            text: v.text,
            title: v.title,
            id: uId,
            style: v.style || ""
          });
          this.marker.updateStyle(Object.assign(v, { id: uId }));
        });
      }
    },
    setMarkDataAndToday(data) {
      this.setMarkData(data);
    },
    isHasNotEditor(target) {
      return this.gantConfig.inlineEdit && hasKey(target, "editMode");
    },
    // 初始化表头参数
    initGantColumnConfig(data) {
      const defaultConfig = {
        resize: true
      };
      const result = data.map((v) => {
        console.log(v.tree, "v.tree", v.checkbox);
        const json = {
          name: v.props,
          template:
            v.checkbox || v.tree
              ? (item) => createCheckBoxTemplate(this.gantt, item)
              : "",
          ...v,
          label: v.tree
            ? `<div class="caret-wrapper"><div class="caret">+</div><span>${v.label}</span></div>`
            : v.label,
          ...defaultConfig
        };
        if (this.isHasNotEditor(v)) {
          json.editor = getEditType(v.editMode);
        }
        return json;
      });
      gantt.config.columns = result;
    }
  }
};
</script>

<style>
/* .gantt_task_line,.gantt_row{
  height: 50px !important;
} */
.gantt_layout_content {
  overflow: hidden;
}
.caret-wrapper {
  display: flex;
  align-items: center;
}
.caret {
  width: 14px;
  height: 14px;
  background: #fff;
  border: 1px solid #8d8d8e;
  font-size: 14px;
  cursor: pointer;
  line-height: 12px;
  text-align: center;
  margin-right: 8px;
}
.gantt_tree_icon.gantt_close {
  background-image: url("./images/icon-a-public-caret-down.png");
}
.gantt_tree_icon.gantt_open {
  background-image: url("./images/icon-a-public-caret-right.png");
}
.gantt_grid_data .gantt_row:hover {
  background-color: #fff;
}
.gantt_grid_data .gantt_row.odd:hover,
.gantt_grid_data .gantt_row:hover {
  background-color: #fff;
}
.gantt_grid_head_cell {
  text-align: left;
  text-indent: 6px;
  font-size: 14px;
  color: #1c1c1e !important;
  font-weight: 400;
}
.gantt_grid_scale .gantt_grid_head_cell:first-child {
  padding-left: 20px;
  text-indent: 0px;
}
.checkboxCls {
  position: relative;
  top: 1px;
}
.gantt_tree_content {
  font-size: 14px;
  /* display: flex; */
  /* align-items: center; */
}
.parent_row_class {
  border: none;
  height: 0px !important;
}
.parent_row_class .gantt_task_progress_wrapper {
  height: 5px;
  background: #d2d2d2;
  top: 21px;
  line-height: 0px;
  color: black;
  overflow: visible;
  font-size: 18px;
  position: relative;
  border-radius: 0;
}
.parent_row_class .gantt_task_progress_wrapper::after {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  border-top: 5px solid #d2d2d2;
  border-left: 5px solid transparent;
  right: 0px;
  top: 4px;
}

.parent_row_class .gantt_task_progress_wrapper::before {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  border-top: 5px solid #d2d2d2;
  border-right: 5px solid transparent;
  left: 0px;
  top: 4px;
}

.parent_row_class .gantt_task_progress {
  background-color: transparent;
}
.parent_row_class .gantt_task_content {
  color: black;
  height: 10px;
  overflow: visible;
  font-size: 12px;
  top: -5px;
  color: #8d8d8e;
  text-align: left;
}
.parent_row_class .gantt_link_control {
  display: none;
}

.parent_row_class .gantt_task_progress_drag {
  display: none !important;
}
.gantt_grid_data .gantt_row.gantt_selected,
.gantt_grid_data .gantt_row.odd.gantt_selected,
.gantt_task_row.gantt_selected {
  background-color: #fff;
}
.gantt_task_row.gantt_selected .gantt_task_cell {
  border-right-color: #ebebeb;
}
.yearHeader {
  position: relative;
  display: flex;
}

.gantt_grid_resize_wrap {
  position: relative;
}
.gantt_layout_outer_scroll {
  position: relative;
  overflow: visible;
}
.gantt_resizer_x .gantt_resizer_x {
  overflow: visible;
}
.weekend {
  background: #f4f7f4 !important;
}
.gantt_layout_content {
  position: relative;
}
.gantt_task_row {
  border-bottom: none;
}
.gantt_task_row:last-child {
  border-bottom: 1px solid #ebebeb;
}
.gantt_row:last-child {
  border-bottom: 1px solid #ebebeb !important;
}
.gantt_task_scale .gantt_scale_line:first-child .gantt_scale_cell {
  text-align: left;
  text-indent: 25px;
}
.ganttwrapper {
  position: relative;
  height: 100%;
}
.ganttwrapper__header {
  position: absolute;
  right: 15px;
  top: 10px;
}
.gantt_task .gantt_task_scale .gantt_scale_cell {
  border-right: none;
}
.gantt_tree_icon.gantt_file,
.gantt_tree_icon.gantt_folder_closed {
  display: none;
}
.gantt_tree_icon.gantt_folder_open {
  display: none;
}
.gantt_tree_content {
  overflow: hidden;
  text-overflow: ellipsis;
}
.parent_node .gantt_tree_content {
  color: #1c1c1e;
  font-weight: 500;
}
.gantt_row,
.gantt_task_row {
  border-bottom: none;
}
</style>
